<template>
  <el-card class="spu-card">
    <el-form
      label-width="100px"
      :model="spuFormData"
      :rules="spuFormRules"
      ref="spuFormRef"
    >
      <el-form-item label="SPU名称" prop="spuName">
        <el-input
          placeholder="请输入SPU名称"
          v-model="spuFormData.spuName"
        ></el-input>
      </el-form-item>
      <el-form-item label="品牌" prop="tmId">
        <el-select placeholder="请选择品牌" v-model="spuFormData.tmId">
          <el-option
            v-for="tm in trademarkList"
            :key="tm.id"
            :label="tm.tmName"
            :value="tm.id"
          ></el-option>
        </el-select>
      </el-form-item>
      <el-form-item label="SPU描述" prop="description">
        <el-input
          placeholder="请输入SPU描述"
          :rows="2"
          type="textarea"
          v-model="spuFormData.description"
        ></el-input>
      </el-form-item>
      <el-form-item label="SPU图片" prop="spuImageList">
        <el-upload
          :class="{
            'spu-upload':
              spuFormData.spuImageList.length >= MAX_UPLOAD_IMG_LENGTH,
          }"
          v-model:file-list="spuFormData.spuImageList"
          action="/app-dev/admin/product/fileUpload"
          list-type="picture-card"
          :on-preview="handlePictureCardPreview"
          :on-remove="handleRemove"
          :before-upload="beforeAvatarUpload"
          :limit="MAX_UPLOAD_IMG_LENGTH"
          :on-success="handleUploadSuccess"
        >
          <el-icon><Plus /></el-icon>
          <template #tip>
            <div class="el-upload__tip">只能上传jpg/png文件，且不超过200kb</div>
          </template>
        </el-upload>
        <el-dialog v-model="dialogVisible" width="340px">
          <img class="spu-img" :src="dialogImageUrl" alt="Preview Image" />
        </el-dialog>
      </el-form-item>
      <el-form-item label="销售属性" prop="spuSaleAttrList">
        <el-select
          :placeholder="`还剩${filterBaseSaleAttrList.length}个未选择`"
          v-model="selectedBaseSaleAttr"
        >
          <el-option
            v-for="baseSaleAttr in filterBaseSaleAttrList"
            :key="baseSaleAttr.id"
            :label="baseSaleAttr.name"
            :value="`${baseSaleAttr.id}:${baseSaleAttr.name}`"
          ></el-option>
        </el-select>
        <el-button
          type="primary"
          :icon="Plus"
          class="spu-btn"
          :disabled="!selectedBaseSaleAttr"
          @click="addSaleAttr"
          >添加销售属性</el-button
        >
        <el-table :data="spuFormData.spuSaleAttrList" border class="spu-table">
          <el-table-column
            type="index"
            label="序号"
            width="60"
            align="center"
          ></el-table-column>
          <el-table-column label="属性名" prop="saleAttrName"></el-table-column>
          <el-table-column label="属性值名称列表" prop="xxx">
            <template v-slot="{ row }">
              <el-tag
                v-for="(saleAttrValue, index) in row.spuSaleAttrValueList"
                :key="saleAttrValue.saleAttrValueName"
                closable
                class="spu-tag"
                @close="delSaleAttrValue(row, index)"
              >
                {{ saleAttrValue.saleAttrValueName }}
              </el-tag>
              <el-input
                v-if="row.isEdit"
                size="small"
                ref="input"
                class="spu-input"
                placeholder="请输入属性值"
                v-model="currentSaleAttrValue"
                @blur="goShow(row)"
              />
              <el-button
                v-else
                :icon="Plus"
                size="small"
                @click="goEdit(row)"
              />
            </template>
          </el-table-column>

          <el-table-column label="操作">
            <template v-slot="{ $index }">
              <el-tooltip content="删除属性" placement="top" effect="light">
                <el-button
                  size="small"
                  type="danger"
                  :icon="Delete"
                  @click="delSaleAttr($index)"
                ></el-button>
              </el-tooltip>
            </template>
          </el-table-column>
        </el-table>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" @click="submitForm">确定</el-button>
        <el-button @click="emit('setIsShow', 1)">取消</el-button>
      </el-form-item>
    </el-form>
  </el-card>
</template>

<script lang="ts">
export default {
  name: 'SaveOrUpdateSpu',
}
</script>

<script lang="ts" setup>
import { Plus, Delete } from '@element-plus/icons-vue'
import { ref, reactive, onMounted, computed, nextTick } from 'vue'
import type { UploadProps, FormRules, FormInstance } from 'element-plus'
import {
  getBaseSaleAttrListApi,
  saveSpuApi,
  getSpuImageListApi,
  getSpuSaleAttrListApi,
  updateSpuApi,
} from '@/api/product/spu'
import { getAllTrademarkListApi } from '@/api/product/trademark'
import type {
  BaseSaleAttrList,
  SaveSpuItem,
  SpuSaleAttrItem,
} from '@/api/product/model/spuModel'
import type { TrademarkList } from '@/api/product/model/trademarkModel'
import { ElMessage } from 'element-plus'
import { useCategoryStore } from '@/stores/category'
const props = defineProps<{
  spu: SaveSpuItem
}>()
const spuFormData = reactive<SaveSpuItem>(props.spu)

// // 表单数据和规则
// const spuFormData = reactive({
//   // 表单数据名称，一定（尽量）要和发送请求需要的数据名称一致
//   spuName: '',
//   tmId: undefined,
//   description: '',
//   spuImageList: [],
//   spuSaleAttrList: [],
// })

const spuFormRef = ref<FormInstance>()
// 最大上传图片的数量

const spuSaleAttrListValidator = (rule: any, value: any, callback: any) => {
  /*
    rule 对象，包含规则的信息
    value 数据的值
    callback 函数，必须要调用
      callback(new Error('xxx')) 表单校验失败
      callback() 表单校验成功

    1. 至少添加一个销售属性
    2. 每个销售属性至少添加一个属性值
  */
  // 1. 至少添加一个销售属性
  if (!value.length) {
    callback(new Error('请至少添加一个销售属性'))
    return
  }

  // 2. 每个销售属性至少添加一个属性值
  if (
    value.some(
      (saleAttr: SpuSaleAttrItem) => !saleAttr.spuSaleAttrValueList.length
    )
  ) {
    callback(new Error('每个销售属性至少添加一个属性值'))
    return
  }

  // 校验通过
  callback()
}
const MAX_UPLOAD_IMG_LENGTH = 10
const spuFormRules = reactive<FormRules>({
  spuName: [{ required: true, message: '请输入SPU名称', trigger: 'blur' }],
  tmId: [{ required: true, message: '请选择品牌', trigger: 'blur' }],
  description: [{ required: true, message: '请输入SPU描述', trigger: 'blur' }],
  spuImageList: [{ required: true, message: '请至少上传一张图片' }],
  spuSaleAttrList: [{ required: true, validator: spuSaleAttrListValidator }],
})
// 图片上传之前触发的函数
const beforeAvatarUpload: UploadProps['beforeUpload'] = (rawFile) => {
  // rawFile 上传的图片文件
  // rawFile.type 图片类型
  // rawFile.size 图片大小
  const typeFiles = ['image/jpeg', 'image/jpg', 'image/png', 'image/gif']
  if (!typeFiles.includes(rawFile.type)) {
    ElMessage.error('上传图片格式必须是jpg或png或gif!')
    return false // 不会上传图片
  } else if (rawFile.size / 1024 > 2000) {
    ElMessage.error('上传图片大小不能超过200kb!')
    return false
  }
  return true // 继续上传图片
}
// 图片上传成功
const handleUploadSuccess = () => {
  // 如果上传了两张以上图片，就不可能出现表单校验失败的错误信息，就不用清空了
  if (spuFormData.spuImageList.length > 1) return
  // 图片上传成功, 至少有一张图片
  spuFormRef.value?.clearValidate(['spuImageList'])
}

// 所有品牌列表
const trademarkList = ref<TrademarkList>([])
// 基础销售属性列表
const baseSaleAttrList = ref<BaseSaleAttrList>([])

// 选中的基础销售属性
const selectedBaseSaleAttr = ref('')
// 添加销售属性
const addSaleAttr = () => {
  const [id, saleAttrName] = selectedBaseSaleAttr.value.split(':')
  // 1. 添加销售属性
  spuFormData.spuSaleAttrList.push({
    saleAttrName, // 销售属性名称
    baseSaleAttrId: +id, // 销售属性id 切割的id是字符串类型，转number
    isEdit: false, // 默认需要显示：显示模式
    spuSaleAttrValueList: [], // 销售属性值列表
  })
  // 2. 选中的值清空
  selectedBaseSaleAttr.value = ''
}

// 删除销售属性
const delSaleAttr = (index: number) => {
  spuFormData.spuSaleAttrList.splice(index, 1)
}

// 删除销售属性值
const delSaleAttrValue = (row: SpuSaleAttrItem, index: number) => {
  row.spuSaleAttrValueList.splice(index, 1)
}

const filterBaseSaleAttrList = computed(() => {
  return baseSaleAttrList.value.filter((baseSaleAttr) => {
    // 判断当前遍历的销售属性，是不是已添加的销售属性
    // 如果是已添加的销售属性，需要过滤，false
    // 如果不是已添加的销售属性，需要保留，true
    // some方法返回值true，说明当前销售属性是已添加的销售属性，取反
    return !spuFormData.spuSaleAttrList.some(
      (saleAttr) => saleAttr.baseSaleAttrId === baseSaleAttr.id
    )
  })
})
// 当前正在输入的销售属性值
const currentSaleAttrValue = ref('')
const input = ref()
// 切换到编辑模式
const goEdit = async (row: SpuSaleAttrItem) => {
  row.isEdit = true
  await nextTick()
  input.value.focus()
}
// 切换到显示模式
const goShow = (row: SpuSaleAttrItem) => {
  row.isEdit = false
  if (!currentSaleAttrValue.value) return
  // 有值才会添加
  // 将输入销售属性值添加上去
  row.spuSaleAttrValueList.push({
    baseSaleAttrId: row.baseSaleAttrId,
    saleAttrValueName: currentSaleAttrValue.value,
  })
  // 将值清空
  currentSaleAttrValue.value = ''
}
// onMounted(async () => {
//   // vue2中可以这样做
//   await Promise.all([getAllTrademarkListApi(), getBaseSaleAttrListApi()]);
// });
const categoryStore = useCategoryStore()

// 上传spu
const submitForm = () => {
  spuFormRef.value?.validate(async (valid) => {
    if (valid) {
      const data = {
        ...spuFormData,
        category3Id: categoryStore.category3Id,
        spuImageList: spuFormData.spuImageList.map((img) => {
          return {
            imgName: img.name,
            // 如果是新添加的图片，图片地址在img.response.data
            // 如果是更新Spu中已有图片，图片地址在img.url
            imgUrl: img.response ? (img.response as any).data : img.url,
          }
        }),
      }

      if (spuFormData.id) {
        await updateSpuApi(data)
      } else {
        // 添加
        await saveSpuApi(data)
      }

      ElMessage.success(`${spuFormData.id ? '更新' : '添加'}Spu成功`)
      emit('setIsShow', 1)
    }
  })
}

onMounted(async () => {
  // 不好，先发一个，等第一个完事，再发第二个，太慢了
  // trademarkList.value = await getAllTrademarkListApi();
  // baseSaleAttrList.value = await getBaseSaleAttrListApi();
  trademarkList.value = await getAllTrademarkListApi()
})

onMounted(async () => {
  baseSaleAttrList.value = await getBaseSaleAttrListApi()
})

const emit = defineEmits(['setIsShow'])
// const fileList = ref<UploadUserFile[]>([
//   {
//     name: 'food.jpeg',
//     url: 'https://fuss10.elemecdn.com/3/63/4e7f3a15429bfda99bce42a18cdd1jpeg.jpeg?imageMogr2/thumbnail/360x360/format/webp/quality/100',
//   },
// ])

const dialogImageUrl = ref('')
const dialogVisible = ref(false)

const handleRemove: UploadProps['onRemove'] = (uploadFile, uploadFiles) => {
  console.log(uploadFile, uploadFiles)
}

const handlePictureCardPreview: UploadProps['onPreview'] = (uploadFile) => {
  dialogImageUrl.value = uploadFile.url as string
  dialogVisible.value = true
}
</script>

<style scoped>
.spu-card {
  margin-top: 20px;
}

.spu-btn {
  margin-left: 10px;
}
.spu-table {
  margin-top: 10px;
}
.spu-img {
  width: 300px;
  height: 300px;
}
.spu-input {
  width: 200px;
}
</style>
<style>
.spu-upload .el-upload--picture-card {
  display: none;
}
</style>
